﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Runtime.Serialization;

namespace _2.StudentsRecords
{
    public class SerializerHelper
    {
        public static void AppendStudentToFile(string fileName, Student student)
        {
            using (FileStream stream = new FileStream(fileName, FileMode.OpenOrCreate, FileAccess.Write))
            {
                stream.Seek(stream.Length, SeekOrigin.Begin);
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(stream, student);
            }
        }

        public static List<Student> GetStudentsFromFile(string fileName)
        {
            List<Student> students = new List<Student>();

            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.Read))
            {
                BinaryFormatter bf = new BinaryFormatter(); 

                while (stream.Position < stream.Length)
                {
                    //Console.WriteLine("{0} : {1}", stream.Position, stream.Length); 
                    
                    object o = bf.Deserialize(stream); 
                    Student s = (Student)o; 
                    students.Add(s); 
                }
            }

            return students;
        }

        public static void DeleteAllStudentsWithFN(string fileName, int fn)
        {
            List<long> startPositions = new List<long>();
            List<int> lengths = new List<int>();

            long startPosition = 0;            

            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
            {                
                BinaryFormatter bf = new BinaryFormatter();

                while (stream.Position < stream.Length)
                {
                    //Console.WriteLine("{0} : {1}", stream.Position, stream.Length);

                    startPosition = stream.Position;

                    object o = bf.Deserialize(stream);
                    Student s = (Student)o;

                    if (s.FN == fn)
                    {
                        int length = (int)(stream.Position - startPosition);

                        startPositions.Add(startPosition);
                        lengths.Add(length);                                                               
                    }
                }
            }

            for (int i = startPositions.Count - 1; i >= 0; i--)
            {
                SerializerHelper.ShiftBytesToLeft(fileName, startPositions[i], lengths[i]);
            }
        }

        public static void ShiftBytesToLeft(string fileName, long startPosition, int length)
        {            
            using (FileStream stream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
            {
                stream.Seek(startPosition, SeekOrigin.Begin);

                int BufferSize = 4096;
                byte[] buffer = new byte[BufferSize];

                while (stream.Position + length < stream.Length)
                {
                    stream.Seek(length, SeekOrigin.Current);

                    int portionSize = (int)Math.Min(BufferSize, stream.Length - stream.Position);
                    stream.Read(buffer, 0, portionSize);

                    stream.Seek(-portionSize - length, SeekOrigin.Current);
                    stream.Write(buffer, 0, portionSize);                    
                }

                stream.SetLength(stream.Position);
            }
        }
    }
}
